using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Management.Automation;
using System.Management.Automation.Host;
using System.Security;

namespace Wolfpack.Contrib.Checks.Powershell
{
    /// <summary>
    /// Defines the custom host functionality that is used to perform dialog-oriented 
    /// and line-oriented interaction, such as writing to, prompting for, and reading 
    /// from user input.
    /// </summary>
    internal class WolfpackPSHostUserInterface : PSHostUserInterface
    {
        private readonly PSHostRawUserInterface _rawUserInterface;
        private readonly IWolfpackPowerShellHost _host;

        /// <summary>
        /// Initializes a new instance of the <see cref="WolfpackPSHostUserInterface"/> class.
        /// </summary>
        /// <param name="host">The wolfpack host.</param>
        /// <param name="rawUserInterface"></param>
        internal WolfpackPSHostUserInterface(IWolfpackPowerShellHost host, PSHostRawUserInterface rawUserInterface)
        {
            if (host == null)
            {
                throw new ArgumentNullException("host");
            }

            if (rawUserInterface == null)
            {
                throw new ArgumentNullException("rawUserInterface");
            }

            _rawUserInterface = rawUserInterface;
            _host = host;
        }

        /// <summary>
        /// Reads characters that are entered by the user until a newline (carriage return) is encountered.
        /// </summary>
        /// <returns>The characters that are entered by the user.</returns>
        /// <exception cref="NotImplementedException">
        /// Scripts hosted by Wolfpack must not call this method.
        /// </exception>
        public override string ReadLine()
        {
            throw WolfpackPSHost.InvalidOperation();
        }

        /// <summary>
        /// Reads characters entered by the user until a newline (carriage return) is 
        /// encountered and returns the characters as a secure string. 
        /// </summary>
        /// <returns>
        /// A <see cref="SecureString"/> object that contains the characters that are entered by the user.
        /// </returns>
        /// <exception cref="NotImplementedException">
        /// Scripts hosted by Wolfpack must not call this method.
        /// </exception>
        public override SecureString ReadLineAsSecureString()
        {
            throw WolfpackPSHost.InvalidOperation();
        }

        /// <summary>
        /// Writes characters to the output display of the host.
        /// </summary>
        /// <param name="value">The characters to be written.</param>
        public override void Write(string value)
        {
            _host.Write(value);
        }

        /// <summary>
        /// Writes characters to the output display of the host with possible foreground and background colors. 
        /// </summary>
        /// <param name="foregroundColor">The foreground color of the display.</param>
        /// <param name="backgroundColor">The background color of the display.</param>
        /// <param name="value">The characters to be written.</param>
        public override void Write(ConsoleColor foregroundColor, ConsoleColor backgroundColor, string value)
        {
            _host.Write(foregroundColor, backgroundColor, value);
        }

        /// <summary>
        /// Writes a new line character (carriage return) to the output display of the host.
        /// </summary>
        /// <param name="value">The line of characters to be written.</param>
        public override void WriteLine(string value)
        {
            _host.WriteLine(value);
        }

        /// <summary>
        /// Writes a line to the error display of the host. 
        /// </summary>
        /// <param name="value">The line of characters to be written.</param>
        public override void WriteErrorLine(string value)
        {
            _host.WriteErrorLine(value);
        }

        /// <summary>
        /// Displays a debug message to the user. 
        /// </summary>
        /// <param name="message">Debug message to be displayed.</param>
        public override void WriteDebugLine(string message)
        {
            _host.WriteDebugLine(message);
        }

        /// <summary>
        /// Writes a progress report to be displayed to the user. 
        /// </summary>
        /// <param name="sourceId">
        /// Unique identifier of the source of the record. An int64 is used because the 
        /// 'this' pointer of the command where the record originated from is used, and 
        /// that may be from a remote runspace on a 64-bit computer.
        /// </param>
        /// <param name="record">
        /// A <see cref="ProgressRecord"/> object that contains the progress record to be displayed.
        /// </param>
        /// <remarks>
        /// This method is invoked by a cmdlet call to the <see cref="WriteProgress"/> method.
        /// </remarks>
        public override void WriteProgress(long sourceId, ProgressRecord record)
        {
            _host.WriteProgress(sourceId, record);
        }

        /// <summary>
        /// Writes a verbose line to be displayed to the user. 
        /// </summary>
        /// <param name="message">The verbose message to be displayed.</param>
        public override void WriteVerboseLine(string message)
        {
            _host.WriteVerboseLine(message);
        }

        /// <summary>
        /// Writes a warning line to be displayed to the user. 
        /// </summary>
        /// <param name="message">The warning message to be displayed.</param>
        public override void WriteWarningLine(string message)
        {
            _host.WriteWarningLine(message);
        }

        /// <exception cref="NotImplementedException">
        /// Scripts hosted by Wolfpack must not call this method.
        /// </exception>
        public override Dictionary<string, PSObject> Prompt(string caption, string message, Collection<FieldDescription> descriptions)
        {
            throw WolfpackPSHost.InvalidOperation();
        }

        /// <exception cref="NotImplementedException">
        /// Scripts hosted by Wolfpack must not call this method.
        /// </exception>
        public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName)
        {
            throw WolfpackPSHost.InvalidOperation();
        }

        /// <exception cref="NotImplementedException">
        /// Scripts hosted by Wolfpack must not call this method.
        /// </exception>
        public override PSCredential PromptForCredential(string caption, string message, string userName, string targetName, PSCredentialTypes allowedCredentialTypes, PSCredentialUIOptions options)
        {
            throw WolfpackPSHost.InvalidOperation();
        }

        /// <exception cref="NotImplementedException">
        /// Scripts hosted by Wolfpack must not call this method.
        /// </exception>
        public override int PromptForChoice(string caption, string message, Collection<ChoiceDescription> choices, int defaultChoice)
        {
            throw WolfpackPSHost.InvalidOperation();
        }

        /// <summary>
        /// Gets an instance of the <see cref="PSHostRawUserInterface "/> interface that is 
        /// implemented by the host application. This interface defines the 
        /// low-level functionality of the custom host. 
        /// </summary>
        public override PSHostRawUserInterface RawUI
        {
            get { return _rawUserInterface; }
        }
    }
}